home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / AEWIN100.ARJ / BASEWIN.CC < prev    next >
C/C++ Source or Header  |  1991-10-27  |  6KB  |  285 lines

  1. /**********************************************************************
  2.  *  
  3.  *  NAME:           basewin.cpp
  4.  *  
  5.  *  DESCRIPTION:    
  6.  *  
  7.  *  copyright (c) 1990 J. Alan Eldridge
  8.  * 
  9.  *  M O D I F I C A T I O N   H I S T O R Y
  10.  *
  11.  *  when        who                 what
  12.  *  -------------------------------------------------------------------
  13.  *  11/??/90    J. Alan Eldridge    created
  14.  *  
  15.  *********************************************************************/
  16.  
  17. #include    "w.h"
  18.  
  19. //  local defines
  20.  
  21. #define PRINTF_MAX  512 //  size of string buffer for printf()
  22.  
  23. //  Unix Curses clears to end of line on newline ...
  24. //  set NL_DOES_CLREOL to 0 if you do not want this behavior
  25. #define NL_DOES_CLREOL  1   
  26.  
  27. //  destructor
  28.  
  29. basewin::~basewin()
  30. {
  31.     if (state == OK) {
  32.         delete xdirty;
  33.         state = ERR;
  34.     }
  35. }
  36.  
  37. //  constructor
  38.  
  39. basewin::basewin(
  40.     int yul,    int xul,
  41.     int ylr,    int xlr):
  42.         vidbuf(yul, xul, ylr, xlr),
  43.         viewport(0, 0, ylr - yul, xlr - xul)
  44. {
  45.     if (state == OK) {
  46.         if (!(xdirty = new int [ ylr - yul ][ 2 ]))
  47.             state = ERR;
  48.     }
  49.     if (state == OK) {
  50.         zflags();
  51.         unmark();
  52.         att = vid_defaultatt;
  53.         clear();
  54.     }
  55. }
  56.     
  57. //  clear current port
  58.  
  59. basewin &
  60. basewin::clear(uchar ch)
  61.     setpos(0,0); 
  62.     vidbuf::clear(yUL,xUL,yLR,xLR,ch,att); 
  63.     touch();
  64.     return *this;
  65. }
  66.  
  67. //  clear to end of line
  68.  
  69. basewin &
  70. basewin::clreol(uchar ch)
  71. {
  72.     if (xCur <= xLR) {
  73.         mark(yCur);
  74.         markline(yCur, xCur);
  75.         markline(yCur, xLR);
  76.         clrline(yCur, xCur, xLR, ch, att);
  77.     }
  78.     return *this;
  79. }
  80.  
  81. //  newline (implies carriage return)
  82.  
  83. basewin &
  84. basewin::NL()
  85. {
  86. #if NL_DOES_CLREOL
  87.     clreol();
  88. #endif    
  89.     CR();
  90.     if (yCur < yLR) {
  91.         yCur++;
  92.     } else if (fScroll) {
  93.         scroll();
  94.     }
  95.     return *this;
  96. }
  97.  
  98. //  carriage return
  99.     
  100. basewin &
  101. basewin::CR()
  102. {
  103.     xCur = xUL;
  104.     return *this;
  105. }
  106.     
  107. //  non-destructive backspace
  108.  
  109. basewin &
  110. basewin::BS()
  111. {
  112.     if (xCur > xUL) {
  113.         xCur--;
  114.     } else if (yCur > yUL) {
  115.         yCur--;
  116.         xCur = xLR;
  117.     }
  118.     return *this;
  119. }
  120.     
  121. //  put a single character
  122.  
  123. basewin &
  124. basewin::put(uchar ch)
  125. {
  126.     if (ch == '\r')
  127.         return CR();
  128.     else if (ch == '\n')
  129.         return NL();
  130.     else if (ch == '\b')
  131.         return BS();
  132.     else if (xCur <= xLR) {
  133.         mark(yCur);
  134.         markline(yCur, xCur);
  135.         putchr(yCur, xCur++, ch, att);
  136.         if (xCur > xLR && fWrap) {
  137.             NL();
  138.         }
  139.     }
  140.     return *this;
  141. }
  142.  
  143. //  put a string
  144.  
  145. basewin &
  146. basewin::put(uchar *s)
  147. {
  148.     while (*s) {
  149.         put(*s++);
  150.     }
  151.     return *this;
  152. }
  153.  
  154. basewin &
  155. basewin::center(int line, uchar *s)
  156. {
  157.     int skip = (cols - strlen(s))/2;
  158.     
  159.     if (skip < 0) 
  160.         skip = 0;
  161.     setpos(line, 0);
  162.     clreol();
  163.     setpos(yCur, skip);
  164.     return put(s);
  165. }    
  166.  
  167. //  printf to current position
  168.  
  169. basewin &
  170. basewin::printf(uchar *fmt, ...)
  171. {
  172.     uchar   buf[PRINTF_MAX];
  173.     va_list ap;
  174.     
  175.     va_start(ap, fmt);
  176.     vsprintf(buf, fmt, ap);
  177.     va_end(ap);
  178.     return put(buf);
  179. }
  180.  
  181. //  mark row as dirty (does NOT set line dirty markers)
  182.  
  183. void
  184. basewin::mark(int row)
  185. {
  186.     if (row < ydirty[0]) ydirty[0] = row;
  187.     if (row > ydirty[1]) ydirty[1] = row;
  188. }
  189.  
  190. //  mark position on line as dirty
  191.  
  192. void
  193. basewin::markline(int row, int col)
  194. {
  195.     if (col < xdirty[row][0]) xdirty[row][0] = col;
  196.     if (col > xdirty[row][1]) xdirty[row][1] = col;
  197. }
  198.     
  199. //  unmark everything (nothing to redraw)
  200.  
  201. void
  202. basewin::unmark()
  203. {
  204.     ydirty[0] = INT_MAX; ydirty[1] = 0;
  205.     for (int y = 0; y < rows; y++) {
  206.         xdirty[y][0] = INT_MAX; xdirty[y][1] = 0;
  207.     }
  208. }    
  209.         
  210. //  mark a region as dirty
  211.  
  212. void
  213. basewin::touch(
  214.     int     yul,
  215.     int     xul,
  216.     int     ylr,
  217.     int     xlr)
  218. {
  219.     mark(yul);
  220.     mark(ylr);
  221.     for (int y = yul; y <= ylr; y++) {
  222.         markline(y, xul);
  223.         markline(y, xlr);
  224.     }
  225. }
  226.  
  227. //  update to display screen
  228.  
  229. void 
  230. basewin::refresh(int vflag)
  231. {
  232.     if (state != OK)
  233.         return;
  234.  
  235.     for (int y = ydirty[0], ylim = ydirty[1]; y <= ylim; y++) {
  236.         int x = xdirty[y][0], xlim = xdirty[y][1];
  237.  
  238.         if (x <= xlim)
  239.             display(y, x, xlim - x + 1, vflag);
  240.     }
  241.     unmark();
  242.     setcursor(vflag);
  243. }
  244.     
  245. //  scroll a section of a window
  246.  
  247. void
  248. basewin::scroll(
  249.     int yul,
  250.     int xul,
  251.     int ylr,
  252.     int xlr,
  253.     int nLines)
  254. {
  255.     if (nLines) {
  256.         int absLines = abs(nLines);
  257.  
  258.         //  3 choices here: clear it, scroll up, or scroll down
  259.  
  260.     if (absLines > ylr - yul) {
  261.             vidbuf::clear(yul, xul, ylr, xlr, ' ', att);
  262.         } else {
  263.             int rows = ylr - yul + 1 - absLines;
  264.             int bytes = (xlr - xul + 1) * sizeof(vidchr);
  265.             
  266.             if (nLines > 0) {
  267.                 //  scroll up
  268.                 for (int r = yul; rows-- > 0; r++) {
  269.                     memcpy(vidptr(r, xul), vidptr(r + nLines, xul), bytes);
  270.                 }
  271.                 vidbuf::clear(r, xul, ylr, xlr, ' ', att);
  272.             } else {
  273.                 //  scroll down
  274.                 for (int r = ylr; rows-- > 0; r--) {
  275.                     memcpy(vidptr(r, xul), vidptr(r + nLines, xul), bytes);
  276.                 }
  277.                 vidbuf::clear(yul, xul, r, xlr, ' ', att);
  278.             }
  279.             touch(yul, xul, ylr, xlr);
  280.         }
  281.     }
  282. }
  283.  
  284.